package cloud.topdaddy.admin.system.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cloud.topdaddy.admin.system.entity.SysDept;
import cloud.topdaddy.admin.system.entity.SysUser;
import cloud.topdaddy.admin.system.service.SysDeptService;
import cloud.topdaddy.admin.system.service.SysUserService;
import cloud.topdaddy.base.common.resp.R;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/sysDept")
public class SysDeptController {
    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private SysUserService sysUserService;

    // 列表（可按名称、父级筛选），按 sort 升序
    @GetMapping("/list")
    @SaCheckLogin
    @SaCheckPermission("system:dept:list")
    public R<List<SysDept>> list(@RequestParam(name = "departmentName", required = false) String departmentName,
                                 @RequestParam(name = "parentId", required = false) Long parentId) {
        var wrapper = sysDeptService.lambdaQuery();
        if (StringUtils.isNotBlank(departmentName)) {
            wrapper.like(SysDept::getDepartmentName, departmentName);
        }
        if (parentId != null) {
            wrapper.eq(SysDept::getParentId, parentId);
        }
        List<SysDept> list = wrapper.orderByAsc(SysDept::getSort).list();
        return R.ok(list);
    }

    // 树结构
    @GetMapping("/tree")
    @SaCheckLogin
    @SaCheckPermission("system:dept:list")
    public R<List<Map<String, Object>>> tree() {
        List<SysDept> depts = sysDeptService.lambdaQuery().orderByAsc(SysDept::getSort).list();
        List<Map<String, Object>> tree = buildTree(depts);
        return R.ok(tree);
    }

    @GetMapping("/{departmentId}")
    @SaCheckLogin
    public R<SysDept> get(@PathVariable("departmentId") Long departmentId) {
        return R.ok(sysDeptService.getById(departmentId));
    }

    @PostMapping("/add")
    @SaCheckLogin
    @SaCheckPermission("system:dept:add")
    public R<String> add(@RequestBody @Valid SysDept dept) {
        dept.setCreateTime(LocalDateTime.now());
        sysDeptService.save(dept);
        return R.ok("新增成功");
    }

    @PutMapping("/update")
    @SaCheckLogin
    @SaCheckPermission("system:dept:update")
    public R<String> update(@RequestBody @Valid SysDept dept) {
        dept.setUpdateTime(LocalDateTime.now());
        sysDeptService.updateById(dept);
        return R.ok("更新成功");
    }

    @DeleteMapping("/delete")
    @SaCheckLogin
    @SaCheckPermission("system:dept:delete")
    public R<String> delete(@RequestParam("ids") List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return R.userErrorParam("ids 不能为空");
        }
        // 子部门校验
        long childCount = sysDeptService.lambdaQuery().in(SysDept::getParentId, ids).count();
        if (childCount > 0) {
            return R.userErrorParam("存在子部门，无法删除");
        }
        // 用户引用校验
        long userRef = sysUserService.lambdaQuery().in(SysUser::getDepartId, ids).count();
        if (userRef > 0) {
            return R.userErrorParam("存在用户归属该部门，无法删除");
        }
        sysDeptService.removeBatchByIds(ids);
        return R.ok("删除成功");
    }

    private List<Map<String, Object>> buildTree(List<SysDept> depts) {
        Map<Long, Map<String, Object>> idNode = new LinkedHashMap<>();
        for (SysDept d : depts) {
            Map<String, Object> node = new LinkedHashMap<>();
            node.put("departmentId", d.getDepartmentId());
            node.put("departmentName", d.getDepartmentName());
            node.put("parentId", d.getParentId());
            node.put("managerId", d.getManagerId());
            node.put("sort", d.getSort());
            node.put("children", new ArrayList<Map<String, Object>>());
            idNode.put(d.getDepartmentId(), node);
        }
        List<Map<String, Object>> roots = new ArrayList<>();
        for (SysDept d : depts) {
            Map<String, Object> node = idNode.get(d.getDepartmentId());
            Long pid = d.getParentId();
            if (pid == null || !idNode.containsKey(pid) || Objects.equals(pid, 0L)) {
                roots.add(node);
            } else {
                List<Map<String, Object>> children = (List<Map<String, Object>>) idNode.get(pid).get("children");
                children.add(node);
            }
        }
        Comparator<Map<String, Object>> cmp = Comparator.comparing(o -> Optional.ofNullable((Integer) o.get("sort")).orElse(0));
        sortTree(roots, cmp);
        return roots;
    }

    @SuppressWarnings("unchecked")
    private void sortTree(List<Map<String, Object>> nodes, Comparator<Map<String, Object>> cmp) {
        nodes.sort(cmp);
        for (Map<String, Object> n : nodes) {
            List<Map<String, Object>> children = (List<Map<String, Object>>) n.get("children");
            if (children != null && !children.isEmpty()) {
                sortTree(children, cmp);
            }
        }
    }
}
